/*************************************************************************
    > File Name: com.c
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: 2022年10月27日 星期四 16时17分00秒
 ************************************************************************/

#include"buffer.h"

int finddir(char *path){                //寻找是否存在文件夹 
	DIR *dir;
	dir = opendir(path);
	if(dir == NULL) return 0;
	else return 1;
}
int find_file(char *path,char *filename){        //在B中寻找文件，非递归 
	DIR *dir;
	int flag = 0;
	struct dirent *entry;
	dir =  opendir(path);
	if(dir == NULL){
		perror("fail to open dir ：find file");
		exit(-1);
	} 
	while((entry = readdir(dir)) != NULL)
	{
		if(strcmp(entry->d_name,filename) == 0)
		{
			flag = 1;
		}
	}
	closedir(dir);
	return flag;
}

int CompareFile(char *file1, char *file2){  //比较文件函数 ，相等返回1，否则返回0 
	FILE *f1,*f2;
	int flag=1; 
	char s1[MAXLEN],s2[MAXLEN];
	f1 = fopen(file1,"r");
	f2 = fopen(file2,"r");
	do{
		fgets(s1,MAXLEN,f1);
		fgets(s2,MAXLEN,f2);
		if(strcmp(s1,s2) != 0)
		{
			flag = 0;
			break;
		}
	}while(!feof(f1) && !feof(f2));   //feof判断文件是否结尾 没有结尾则返回0
	fclose(f1);
	fclose(f2);
	return flag;
}

void dir_traverse1(char *src,char *dest){ //删除B目录中没有的文件和比较同名文件 
	DIR *dir1;
	dir1 = opendir(src);         //打开源目录 
	struct dirent *entry1;
	char path1[200];          //存放子目录的路径 
	char path2[200];
	if (dir1 == NULL){
		perror("fail to open src:");
		exit(-1);
	}
	while(1)
	{
		entry1 = readdir(dir1);
		if(entry1 == NULL) break;
		if((strcmp(entry1->d_name, ".") == 0) || (strcmp( entry1->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(path1,"%s/%s",src,entry1->d_name);
		sprintf(path2,"%s/%s",dest,entry1->d_name);
		//递归目录 
		if(entry1->d_type & DT_DIR){
			if(!finddir(path2))   //B中不存在文件夹,则删除
			{
				char s[200];
				sprintf(s,"rm -rf %s",path1);
				system(s);
				//printf("删除 %s 目录成功！\n",path1);
				sprintf(s,"echo '删除 %s 目录成功！' >>log.txt",path1);  //写入log文件
				system(s);
			}
			else dir_traverse1(path1,path2);
		}
		else          //文件 
		{ 
			if(!find_file(dest,entry1->d_name))  //在B目录中查找文件，没找到，则删除A中的文件 
			{    
				if(remove(path1) == -1)
				{
					perror("fail to remove");
					exit(-1); 
				}
				else
				{
					char s[200];
					sprintf(s,"echo '删除 %s 文件成功！' >>log.txt",path1);  //写入log文件
					system(s);
					//printf("删除 %s 成功！\n",path1);
				}
			}
			else                                //存在同名文件，则比较两个文件 
			{
				if(!CompareFile(path1,path2)) //文件不相同时,复制文件 
				{   
				    char s[200];
				    //printf("\n");
					sprintf(s,"cp -vp %s %s",path2,path1); 
					system(s);
					//printf("%s文件同步成功！\n",path2);
					memset(s, '\0', 200);
					sprintf(s,"echo '%s 文件同步成功！' >>log.txt",path2);  //写入log文件
					system(s);
				}
			}        
		}
	}
	closedir(dir1);
}

void dir_traverse2(char *src,char *dest){         //复制B中存在而A中不存在的文件 
	DIR *dir;
	dir = opendir(dest);        //打开目标目录 
	     //  printf("%s %s\n",src,dest);
	struct dirent *entry;
	char path1[200];          //存放子目录的路径 
	char path2[200];
	if (dir == NULL){
		perror("fail to open dest");
		exit(-1);
	}
	while(1)
	{
		entry = readdir(dir);
		if(entry == NULL) break;
		if((strcmp(entry->d_name, ".") == 0) || (strcmp( entry->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(path1,"%s/%s",src,entry->d_name);   //dest子路径 
		sprintf(path2,"%s/%s",dest,entry->d_name);    //src 子路径 
		//递归目录 
		//printf("%s %s",path1,path2);
		if(entry->d_type & DT_DIR)
		{
			if(!finddir(path1))            //A中不存在该目录则复制 
			{
				char s[200];
				sprintf(s,"cp -vrp %s %s",path2,path1);
				system(s);
				//printf("同步目录 %s 成功！\n",path2);
				memset(s, '\0', 200);
				sprintf(s,"echo '同步目录 %s 成功！' >>log.txt",path2);  //写入log文件
				system(s); 
			}
			dir_traverse2(path1,path2);
		}
		else          //文件 
		{ 
			if(!find_file(src,entry->d_name))  //在A目录中查找文件，没找到，则复制到A中 
			{
				char s[200];
				sprintf(s,"cp -vp %s %s",path2,path1);
				system(s);
				//printf("%s文件同步成功！\n",path1);
				memset(s, '\0', 200);
				sprintf(s,"echo '%s 文件同步成功' >>log.txt",path1);  //写入log文件
				system(s);
			} 
		}
	}
	closedir(dir);
}

void Sync(char *src,char *dest){
        system("echo '------文件同步'>>log.txt");
 
	pid_t pid;
	pid = fork();
	if(pid < 0){
		perror("fail to fork:");
		exit(-1);
	}else if(pid == 0){ //子进程 
		dir_traverse1(src,dest);
		exit(0); 
	}else{              //父进程 
		wait(NULL);
		dir_traverse2(src,dest);
	}
}


void dir_same1(char *src,char *dest){ //删除B目录中没有的文件和比较同名文件 
	DIR *dir1;
	dir1 = opendir(src);         //打开源目录 
	struct dirent *entry1;
	char path1[200];          //存放子目录的路径 
	char path2[200];
	if (dir1 == NULL){
		perror("fail to open src:");
		exit(-1);
	}
	while(1)
	{
		entry1 = readdir(dir1);
		if(entry1 == NULL) break;
		if((strcmp(entry1->d_name, ".") == 0) || (strcmp( entry1->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(path1,"%s/%s",src,entry1->d_name);
		sprintf(path2,"%s/%s",dest,entry1->d_name);
		//递归目录 
		if(entry1->d_type & DT_DIR){
			if(!finddir(path2))   //B中不存在文件夹,则复制该文件夹 
			{
				char s[200];
				sprintf(s,"cp -rvp %s %s",path1,path2);
				system(s);
				//printf("同步 %s 目录成功！\n",path1);
				memset(s, '\0', 200);
				sprintf(s,"echo '同步 %s 目录成功！' >>log.txt",path1);  //写入log文件
				system(s);
			}
			else dir_same1(path1,path2);			
		}
		else          //文件 
		{   
			if(!find_file(dest,entry1->d_name))  //在B目录中查找文件，没找到，则复制A中的文件 
			{
				char s[200];
				//printf("\n");
				sprintf(s,"cp -vp %s %s",path1,path2);
				system(s);
				//printf("%s文件同步成功！\n",path1);
				memset(s, '\0', 200);
				sprintf(s,"echo '%s 文件同步成功！' >>log.txt",path1);  //写入log文件
				system(s);
			}
			else                                //存在同名文件，则比较两个文件 
			{
				if(!CompareFile(path1,path2)) //文件不相同时,以最新的日期为准 
				{   
				    if(LastTime(path1,path2) == 0)
				    {
					    char s[200];
						sprintf(s,"cp -vp %s %s",path1,path2);
						//printf("\n");
						system(s);
						//printf("%s文件同步成功！\n",path1);
						memset(s, '\0', 200);
				        sprintf(s,"echo '相同文件，以时间最新的文件 %s 为准！' >>log.txt",path1);  //写入log文件
			         	system(s);				    	
					}else{
						char s[200];
						sprintf(s,"cp -vp %s %s",path2,path1);
						system(s);
						//printf("%s文件同步成功！\n",path2);	
						memset(s, '\0', 200);
				        sprintf(s,"echo '相同文件，以时间最新的文件 %s 为准！' >>log.txt",path2);  //写入log文件
			         	system(s);						
					}
				}
			}        
		}
	}
	closedir(dir1);
}

void dir_same2(char *src,char *dest){         //复制B中存在而A中不存在的文件 
	DIR *dir;
	dir = opendir(dest);        //打开目标目录 
	struct dirent *entry;
	char path1[200];          //存放子目录的路径 
	char path2[200];
	if (dir == NULL){
		perror("fail to open dest");
		exit(-1);
	}
	while(1)
	{
		entry = readdir(dir);
		if(entry == NULL) break;
		if((strcmp(entry->d_name, ".") == 0) || (strcmp( entry->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(path1,"%s/%s",src,entry->d_name);   //dest子路径 
		sprintf(path2,"%s/%s",dest,entry->d_name);    //src 子路径 
		//递归目录 
		if(entry->d_type & DT_DIR){
			if(!finddir(path1))   //A中不存在文件夹,则复制该文件夹 
			{
				char s[200];
				sprintf(s,"cp -rvp %s %s",path2,path1);
				system(s);
				//printf("同步 %s 目录成功！\n",path2);
				memset(s, '\0', 200);
				sprintf(s,"echo '同步 %s 目录成功！' >>log.txt",path2);  //写入log文件
			    system(s);	
			}
			else dir_same2(path1,path2);
		}
		else          //文件 
		{ 
			if(!find_file(src,entry->d_name))  //在A目录中查找文件，没找到，则复制到A中 
			{
				char s[200];
				//printf("\n"); 
				sprintf(s,"cp -vp %s %s",path2,path1);
				system(s);
				//printf("%s文件同步成功！\n",path1);
				memset(s, '\0', 200);
				sprintf(s,"echo '同步 %s 目录成功！' >>log.txt",path2);  //写入log文件
				system(s); 
			} 
		}
	}
	closedir(dir);
}

void AB_Sync(char *src,char *dest){
        system("echo '------双向同步 A<—>B'>>log.txt");
	pid_t pid;
	pid = fork();
	if(pid < 0){
		perror("fail to fork:");
		exit(-1);
	}else if(pid == 0){ //子进程 
		dir_same1(src,dest);
		exit(0); 
	}else{              //父进程 
		wait(NULL);
		dir_same2(src,dest);
	}
}


int change(char *t,int x,int length){  //将字符转化为数字 
	char s[10]="";
	strncpy(s,t+x,length);
	return atoi(s);
}

int LastTime(char * file1,char *file2){    //比较两个文件最后访问时间，file1最新返回0，file2最新返回1 
	struct stat st1,st2;
	char t1[50],t2[50];
	char s1[10],s2[10];
	int year1,month1,day1,time1=0;
	int year2,month2,day2,time2=0;
	char MONTH[13][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    //读取文件stat 
	stat(file1,&st1);
	stat(file2,&st2);
	strcpy(t1,ctime(&st1.st_mtime));
	strcpy(t2,ctime(&st2.st_mtime));
	//获取月份 
	strncpy(s1,t1+4,3);
	strncpy(s2,t2+4,3); 
	for(int i=0;i<12;i++){
		if(strncmp(MONTH[i],s1,3) == 0){
			month1 = i+1;
		}
		if(strncmp(MONTH[i],s2,3) == 0){
			month2 = i+1;
		}
	}
//	printf("month %d %d\n",month1,month2);
    //获取天数
	day1 = change(t1,8,2);
	day2 = change(t2,8,2);
//	printf("day %d %d\n",day1,day2);
	//获取年份
	year1 = change(t1,20,4);
	year2 = change(t2,20,4);
//	printf("year %d %d\n",year1,year2);	
	//获取当天时间
	time1 = change(t1,11,2)*3600+change(t1,14,2)*60+change(t1,17,2);
	time2 = change(t2,11,2)*3600+change(t2,14,2)*60+change(t2,17,2);
//	printf("time1 %d %d %d  %d\n",change(t1,11,2),change(t1,14,2),change(t1,17,2),time1);
//	printf("time2 %d %d %d  %d\n",change(t2,11,2),change(t2,14,2),change(t2,17,2),time2);
    if(year1 > year2) return 0;
    else if(year1 == year2){
    	if(month1 > month2) return 0;
    	else if(month1 == month2){
    		if(day1 > day2) return 0;
    		else if(day1 == day2){
    			if(time1 > time2){
    				return 0;
				}
			}
		}
	} 
	return 1;	 
}

